using System;
using System.ComponentModel;
using System.Reflection;
using ZoneFiveSoftware.Common.Data;

namespace FilteredStatistics.Common.Controller
{
    class ProxyNamedZone : INamedZone
    {
        public ProxyNamedZone(object namedZone)
        {
            if (namedZone == null)
            {
                throw new Exception("Invalid named zone pointer");
            }

            Type namedZoneType = namedZone.GetType();

            m_NamedZoneObject = namedZone;

            m_NameProperty = namedZoneType.GetProperty("Name", typeof(String));
            m_ValidTimesProperty = namedZoneType.GetProperty("ValidTimes", typeof(IValueRangeSeries<DateTime>));
            m_ValidTimesChangedEvent = namedZoneType.GetEvent("ValidTimesChanged");

            if (m_NameProperty == null ||
                !m_NameProperty.CanRead ||
                m_ValidTimesProperty == null || 
                !m_ValidTimesProperty.CanRead ||
                m_ValidTimesChangedEvent == null)
            {
                throw new Exception("Named zone doesn't implement INamedZone interface");
            }

            m_ValidTimesChangedEvent.AddEventHandler(m_NamedZoneObject, Delegate.CreateDelegate(typeof(PropertyChangedEventHandler), this, "ValidTimesChangedEventHandler"));

            TriggerValidTimesChanged();
        }

#region INamedZone Members

        public String Name
        {
            get
            {
                return m_NameProperty.GetValue(m_NamedZoneObject, null) as String;
            }
        }

        public IValueRangeSeries<DateTime> ValidTimes
        {
            get
            {
                return m_ValidTimesProperty.GetValue(m_NamedZoneObject, null) as IValueRangeSeries<DateTime>;
            }
        }

        public event PropertyChangedEventHandler ValidTimesChanged;

#endregion

        private void ValidTimesChangedEventHandler(object sender, PropertyChangedEventArgs e)
        {
            TriggerValidTimesChanged();
        }

        protected void TriggerValidTimesChanged()
        {
            if (ValidTimesChanged != null)
            {
                ValidTimesChanged(this, new PropertyChangedEventArgs("ValidTimes"));
            }
        }

        private object m_NamedZoneObject = null;
        private PropertyInfo m_NameProperty = null;
        private PropertyInfo m_ValidTimesProperty = null;
        private EventInfo m_ValidTimesChangedEvent = null;
    }
}
